package websocket

import (
	"encoding/json"
	"gg_server/db"
	"gg_server/model"
	"gg_server/util"
	"time"

	"go.mongodb.org/mongo-driver/bson/primitive"
)

// 交互消息 定义
const (
	// 错误消息
	ErrorMsg = iota
	// 正常用户之间聊天时
	Chat
	// 好友请求
	AddFriend
	// 已读消息
	ChatRead
)

type Message struct {
	// 当前发送消息的用户
	CurrentId int `json:"-"`
	// 交互消息的内容
	Type int `json:"type"`
	// 数据
	Data interface{} `json:"data"`
}

// 不合法的消息
type ErrorMsgStruct struct {
	Message string `json:"message"`
}

// 聊天的消息
type ChatMsg struct {
	// 要发送的目标好友对象
	FriendId int `json:"friend_id"`
	// 聊天的记录文档 mongodb
	ChatId string `json:"chat_id"`
	// 聊天的内容
	Message string `json:"message"`
}

// 好友请求
type FriendRequest struct {
	Request model.FriendRequest
}

// 已经读取 聊天记录
type Read struct {
	// 聊天记录id
	ChatId string `json:"chat_id"`
	// 好友id
	FriendId int `json:"friend_id"`
}

// 格式化 消息 并发送
func (m *Message) FormatSendMsg() {
	switch m.Type {
	case ErrorMsg:
		{
			// 错误的消息
			// 发送给客户端
			msg := Message{
				CurrentId: m.CurrentId,
				Type:      ErrorMsg,
				Data: ErrorMsgStruct{
					Message: "消息不合法",
				},
			}
			data, _ := json.Marshal(msg)
			// 向客户端发送消息
			CMHandle.SendMessage(m.CurrentId, data)
		}
	case Chat:
		{
			// 处理聊天消息
			data, _ := json.Marshal(m.Data)
			var chatMsg ChatMsg
			err := json.Unmarshal(data, &chatMsg)
			if err != nil || chatMsg.FriendId == 0 || chatMsg.ChatId == "" {
				m.Type = ErrorMsg
				m.FormatSendMsg()
			}
			chatMsg.Handle(m.CurrentId)
		}
	case AddFriend:
		{
			// 收到好友请求  客户端无需发送任何字段
		}
	case ChatRead:
		{
			// 设置已读消息
			data, _ := json.Marshal(m.Data)
			var read Read
			err := json.Unmarshal(data, &read)
			if err != nil || read.ChatId == "" || read.FriendId == 0 {
				m.Type = ErrorMsg
				m.FormatSendMsg()
			}
			read.Handle()
		}
	}
}

// 发送并储存聊天消息
func (c *ChatMsg) Handle(currentId int) {
	msg := Message{
		CurrentId: currentId,
		Type:      Chat,
		Data:      c,
	}

	_id, err := primitive.ObjectIDFromHex(c.ChatId)
	if err != nil {
		msg.Type = ErrorMsg
		msg.FormatSendMsg()
		return
	}

	chat := model.ChatMsg{
		Date_time: time.Now(),
		Msg:       c.Message,
		Id:        currentId,
		Read:      false,
	}

	// 储存聊天消息
	util.MongoD.PushChatMsg(_id, chat)

	// 获取发送聊天消息的用户信息
	user := model.User{
		Id: currentId,
	}
	db.CreateSQLDB().Find(&user)

	// 向客户端发送消息
	msg = Message{
		Type: Chat,
		Data: map[string]interface{}{
			"chat_id": c.ChatId,
			"user":    user,
			"chat":    chat,
		},
	}
	data, _ := json.Marshal(msg)
	CMHandle.SendMessage(c.FriendId, data)
}

// 好友请求
func (f *FriendRequest) Handle(friend_id int) {
	msg := Message{
		Type: AddFriend,
		Data: map[string]interface{}{
			"friend_require": f.Request,
		},
	}

	data, _ := json.Marshal(msg)
	CMHandle.SendMessage(friend_id, data)
}

// 将消息设置为已读
func (r *Read) Handle() {
	_id, err := primitive.ObjectIDFromHex(r.ChatId)
	if err != nil {
		msg := Message{
			Type: ErrorMsg,
		}
		msg.FormatSendMsg()
		return
	}

	util.MongoD.FindOnUpdateChatRead(_id, r.FriendId, &model.Chat{})
}
